package com.avicsafety.ezsystem.pdf;

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;


import com.avicsafety.ezsystem.R;
import com.avicsafety.ezsystem.utils.DateTime;
import com.avicsafety.ezsystem.utils.SDCardUtils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.CMYKColor;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class PdfManager {

	private Context mContext;

	/**字体文件位置*/
	private static final String FONT_DIR = SDCardUtils.getSDCardPath()+ File.separator+"Fonts";
	private static final String FONT_HWZS = FONT_DIR+ File.separator+"hwzs.ttf";
	private static final String FONT_SIMFANG = FONT_DIR+ File.separator+"simfang.ttf";

	private Boolean showLine = false;

	/**文字行数*/
	private Integer RowSize = 76;

	/**行间距*/
	private static final Integer LineHeight = 20;

	Map<Integer,List<Row>> map = new HashMap<>();

	private int totalPage =1;
	private int currentPage = 1;
	String[] number = new String[]{"","一","二","三","四","五","六","七","八","九","十","",""};
	private List<String> result = new ArrayList<String>();
	Set<Block> mData;
	private int ResIdString1;
	private int ResIdString2;
	private String path;
	private String filename;

	/**标题字体 华文中宋*/
	Font font_hwzs;

	/**仿宋正文*/
	Font font_simfang;

	/**仿宋正文带下滑线*/
	Font font_simfang_line;

	/**仿宋正文文书编号*/
	Font font_simfang_code;

	/**
	 * PDF文档管理器
	 * @param _context
	 */
	public PdfManager(Context _context) {
		this(_context,76);
	}

	/**
	 * PDF文档管理器
	 * @param _context
	 */
	public PdfManager(Context _context, Integer _RowSize) {
		this.mContext = _context;
		this.RowSize = _RowSize;
		initFont();
	}

	/**
	 * 初始化字体 包括华文中宋(用于标题),仿宋正文 和带下划线的仿宋正文 已经文书标号 四种字体
	 */
	private void initFont() {

		FontFactory.register(FONT_HWZS,"hwzs");
		FontFactory.register(FONT_SIMFANG,"simfang");

		font_hwzs = FontFactory.getFont("hwzs", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 16, Font.NORMAL);
		font_simfang = FontFactory.getFont("simfang", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12, Font.NORMAL);
		font_simfang_line = FontFactory.getFont("simfang", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 14, Font.UNDERLINE);
		font_simfang_code = FontFactory.getFont("simfang", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 15, Font.UNDERLINE);
	}


	/**
	 * 第一页模板 资源ID
	 * @param _ResIdString
	 */
	public void setTemplate(int _ResIdString){
		ResIdString1 = _ResIdString;
	}


	/**
	 * 续页模板 资源ID
	 * @param _ResIdString
	 */
	public void setTemplate2(int _ResIdString){
		ResIdString2 = _ResIdString;
	}


	/**
	 * 设置正文 Block组成 包含
	 * @param
	 */
	public void setContext(Set<Block> _mData) {
		mData = _mData;
	}


	/**
	 * 打印正文
	 * @param _path 文件路径
	 * @param _filename 文件名
	 * @return 返回PDF列表
	 * @throws IOException
	 * @throws DocumentException
	 */
	public List<String> makeDocFile(String _path, String _filename) throws IOException, DocumentException {

		String resultPath = _path+ File.separator+_filename;
		List<Row> _list = new ArrayList<>();
		//开始写入文字信息
		for(Block block:mData){

			currentPage = 1;
			//获取内容
			String content = block.getContent();
			//替换掉/r 保留/n
			content = content.replace("\r", "");
			//变成全角和大写
			content = ToSBC(content);
			//格式化正文
			String[] temp = format(content,block.getSize(),block.getHeadIndentNum(),block.getFootIndentNum(),block.getLinkAttachmentText(),block.getRowSize());
			//排除了附页部分
			content = temp[0];

			//插入操作
            String[] array = content.split("\n");
			for(String row:array){
				Phrase phrase = new Phrase(row,font_simfang);
				//* modify by shili at 2018-7-31 增加了文字编码限制,调整了字体大小
				switch(block.getFontCode()){
					case Block.FONT_CODE_CONTENT:{
                        phrase = new Phrase(row,font_simfang);
						break;
					}
					case Block.FONT_CODE_CONTENT_UNDERLINE:{
                        phrase = new Phrase(row,font_simfang_line);
						break;
					}
					case Block.FONT_CODE_DOC_CODE:{
                        phrase = new Phrase(row,font_simfang_code);
						break;
					}
					case Block.FONT_CODE_TITLE:{
                        phrase = new Phrase(row,font_hwzs);
						break;
					}
				}
				//ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, phrase, block.getX(), block.getY(), 0);
				//下一行Y的位置

				_list.add(new Row(currentPage,phrase,block.getX(),block.getY()));

				block.setY(block.getY()-LineHeight);
            }

			map.put(currentPage,_list);

			//插入附页
			if(temp[1].length()>0&&block.getHasAttachment()){
				//已经满足续页条件 打印续页
				makeDocFile2(temp[1],block);
			}
		}

		//新建PDF文档
		Document document = new Document();
		PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(resultPath));
		document.open();
		PdfContentByte cb = writer.getDirectContent();

		//开始读取已经存在的模板
		Resources res = mContext.getResources();
		InputStream is = res.openRawResource(ResIdString1);
		PdfReader template = new PdfReader(is);

		//插入正文
		document.newPage();
		PdfImportedPage page = writer.getImportedPage(template, 1);
		cb.addTemplate(page,0,0);

		//开始画参考线
		cb.saveState();
		if(showLine){
			CMYKColor magentaColor = new CMYKColor(0.f, 1.f, 0.f, 0.f);
			cb.setColorStroke(magentaColor);
			for(int i=0;i<20;i++){
				cb.moveTo(50*i, 0);
				cb.lineTo(50*i, 1000);

				cb.moveTo(0, 50*i);
				cb.lineTo(800, 50*i);

				if(i>0){
					ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,  new Phrase(""+i*50), 50*i, 0, 0);
					ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,  new Phrase(""+i*50), 0, 50*i, 0);
				}

			}
			cb.closePathStroke();
		}

		cb.restoreState();
		//参考线画完

		//获取附页资源
		Resources attachment_res = mContext.getResources();
		InputStream attachment_is = res.openRawResource(ResIdString2);

		//读取这个附页
		PdfReader attachment = new PdfReader(attachment_is);


		for(int i=0;i<totalPage;i++){
			int _page = i+1;
			List<Row> rows = map.get(_page);
			if(_page>1){  //附页处理
				document.newPage();
				PdfImportedPage pdfPage = writer.getImportedPage(attachment, 1);
				cb.addTemplate(pdfPage,0,0);
				ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("续页"+number[_page-1],font_simfang), 480, 745, 0);
			}
			for(Row row:rows){
				ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, row.getPhrase(), row.getmX(), row.getmY(), 0);
			}
			ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("共"+number[totalPage]+"页  第"+number[_page]+"页",font_simfang), 400, 50, 0);

		}

		document.close();
		writer.close();

		return result;
	}


	private void makeDocFile2(String content,Block block) throws IOException, DocumentException {

		totalPage++;

		currentPage = totalPage;

        //格式化正文
        String[] temp = format(content,72*3,0,0,block.getLinkAttachmentText(),72);

        //排除了附页部分
        content = temp[0];

        //插入操作
        String[] array = content.split("\n");

		List<Row> _list = new ArrayList<>();

        Float x = 80f;
        Float y = 680f;
        for(String row:array){
            Phrase phrase = new Phrase(row,font_simfang);
            //* modify by shili at 2018-7-31 增加了文字编码限制,调整了字体大小
            switch(block.getFontCode()){
                case Block.FONT_CODE_CONTENT:{
                    phrase = new Phrase(row,font_simfang);
                    break;
                }
                case Block.FONT_CODE_CONTENT_UNDERLINE:{
                    phrase = new Phrase(row,font_simfang_line);
                    break;
                }
                case Block.FONT_CODE_DOC_CODE:{
                    phrase = new Phrase(row,font_simfang_code);
                    break;
                }
                case Block.FONT_CODE_TITLE:{
                    phrase = new Phrase(row,font_hwzs);
                    break;
                }
            }
			_list.add(new Row(currentPage,phrase,x,y));
            //下一行Y的位置
            y-=LineHeight;
        }

		map.put(currentPage,_list);

        //插入附页
        if(temp[1].length()>0&&block.getHasAttachment()){
            //已经满足续页条件 打印续页
            makeDocFile2(temp[1],block);
        }

	}


	/**
	 * 在pdf上签名或盖章
	 * @param pdf_path pdf文件的路径
	 * @param img_path 盖章或者签名的图片路径
	 * @param x 盖的位置 X
	 * @param y 盖的位置 Y
	 * @param width 盖的区域宽度
	 * @param height 盖的区域高度
	 * @return 返回的PDF路径+ _signed
	 */
	private String sign(String pdf_path, String img_path, Float x, Float y, Float width, Float height){
		String result = "";
		try {
			result = pdf_path.replace(".pdf","")+"_signed.pdf";

			PdfReader template = new PdfReader(pdf_path); //读取pdf 这个是底板
			PdfStamper stamper = new PdfStamper(template, new FileOutputStream(result));

			PdfContentByte over = stamper.getOverContent(1);

			//插入印章 这里也可以替换成签名
			Image img = Image.getInstance(img_path);
			//图像 宽度 u u 高度 x y
			//use addImage(image, image_width, 0, 0, image_height, x, y).
			over.addImage(img, width, 0, 0, height, x, y);
			//over.restoreState();


			stamper.close();

			template.close();

		} catch (IOException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}

		return result;
	}

	/**
	 * 是否显示参考线
	 * @param showLine
	 */
	public void setShowLine(Boolean showLine) {
		this.showLine = showLine;
	}


	
	//格式化字符串. 并将值和放不下的值 放到数组中

	/**
	 * 格式化字符串
	 * @param s 需要的文本
	 * @param icount 区块的文字数量
	 * @param beginIndex 前部缩进
	 * @param endIndex 尾部缩进
	 * @param tip 附页的连接文本提示
	 * @return 返回已经格式化完毕的 还有其他页的字符串
	 */
	private String[] format(String s, Integer icount, Integer beginIndex, Integer endIndex, String tip, Integer RowSize) {

		if(RowSize==0){
			RowSize = this.RowSize;
		}

		//处理缩进
		for(int i=0;i<beginIndex;i++){
			if(i%2==0){
				s="　"+s;
			}
		}

		String[] value = new String[]{"",""};
		tip = tip.replace("xx", number[totalPage]); //接续页 页码
		float fCount = (float)icount-getStringLenght(tip)-endIndex;  //给(接副页)等文字留下位置 自动计算
		float totalIndex = 0;  //从0开始统计
		//过滤掉所有回车符 只保留换行符

		StringBuffer sb = new StringBuffer("");
		//初始化列计数器
		float cloumIndex = 0;
		
		//遍历字符串所有符号 进行换行处理
		for(int i=0;i<s.length();i++){
			if(totalIndex<fCount){
				if(s.charAt(i)=='\n'||cloumIndex>=RowSize){
					//遍历时 发现换行符 或者 满行了 就将列计数器归零
					
					
					if(s.charAt(i)=='\n'){
						//补全空格 76-cloumIndex;
						//final int fixCount = (int) (RowSize-cloumIndex);
						//for(int j=0;j<fixCount;j+=2){
					//		if(totalIndex<=fCount){
					//			sb.append("　");
					//			totalIndex+=2;
					//		}
					//		}
						//if(totalIndex<=fCount){
						sb.append("\n");
						//}
						cloumIndex = 0; //遇到换行符的情况 直接归零
					}else{
						//够数了.开始换行
						sb.append("\n");
						//totalIndex++;
						sb.append(s.charAt(i));
						totalIndex+=getChLenght(s.charAt(i));
						cloumIndex = getChLenght(s.charAt(i));  //字符换到下一页
					}
				}else{
					//如果没满 就增加 到新的sb中
					sb.append(s.charAt(i));
					cloumIndex+=getChLenght(s.charAt(i));
					totalIndex+=getChLenght(s.charAt(i));
				}
				
			}else{
				//超出了极限 分隔成两份
				sb.append(tip);
				value[0] = sb.toString();
				StringBuffer sb2 = new StringBuffer("");
				for(int j=i; j<s.length();j++){
					sb2.append(s.charAt(j));
				}
				value[1] = sb2.toString();
				break;
			}
		}
		
		//处理不够的情况 增加横线布满
//		if(totalIndex<fCount){
//			//循环补全所有内容
//			//取消掉一开始为下一页留的位置
//			fCount+=getStringLenght(tip);
//			for(int i=0; i<fCount-totalIndex;i+=2){
//				if(cloumIndex>=RowSize){
//					//遍历时满行了 就将列计数器归零
//					cloumIndex = 0;
//					sb.append("\n");
//					i-=2;
//				}else{
//					//如果没满 就增加 到新的sb中
//					sb.append("　");
//					cloumIndex+=2;
//				}
//			}
//		}
		value[0] = sb.toString();
		return value;
	}

//	private String fix(String s, int count){
//		if(s==null){
//			s = "";
//		}
//		StringBuffer sb = new StringBuffer(s);
//		for(int i=0;i<count-getStringLenght(s);i++){
//			sb.append(" ");
//		}
//		return sb.toString();
//	}

	public float getChLenght(char ch){
		float x = 0;
		if ('\u0030' <= ch && ch <= '\u0039') {
			x = 1.5f;
		} else if ('\u0041' <= ch && ch <= '\u005A') {
			x = 1.5f;
		} else if ('\u0061' <= ch && ch <= '\u007A') {
			x = 1.5f;
		} else if (!(('\uFF61' <= ch) && (ch <= '\uFF9F')) && !(('\u0020' <= ch) && (ch <= '\u007E'))) {
			x = 2;
		} else {
			x = 1.5f;
		}
		return x;
	}
	
	public float getStringLenght(String s){
		float x = 0;
		for(int i=0;i<s.length();i++){
			x+=getChLenght(s.charAt(i));
		}
		return x;
	}
	
	public void test(String path, String WSMC, String WSBH, String CON, String filename) throws IOException, DocumentException {


	}

	
	public static String ToSBC(String input) {
		
		//数字序号
		input = input.replace("1.", "１、");
		input = input.replace("2.", "２、");
		input = input.replace("3.", "３、");
		input = input.replace("4.", "４、");
		input = input.replace("5.", "５、");
		input = input.replace("6.", "６、");
		input = input.replace("7.", "７、");
		input = input.replace("8.", "８、");
		input = input.replace("9.", "９、");
		input = input.replace("0.", "０、");
		
		//标点符号
		input = input.replace(",", "，");
		input = input.replace(".", "。");
		input = input.replace("?", "？");
		input = input.replace("!", "！");
		input = input.replace(":", "：");
		input = input.replace(";", "；");
		
		input = input.replace("(", "（");
		input = input.replace(")", "）");
		input = input.replace("<", "《");
		input = input.replace(">", "》");
		input = input.replace("[", "【");
		input = input.replace("]", "】");		
		input = input.replace("{", "｛");
		input = input.replace("}", "｝");
		
		input = input.replace("`", "` ");
		input = input.replace("@", "@@");
		input = input.replace("#", "＃");
		input = input.replace("$", "＄");
		input = input.replace("%", "％");
		input = input.replace("^", "…");
		input = input.replace("&", "&&");
		input = input.replace("*", "×");
		input = input.replace("_", "——");
		input = input.replace("-", "－");
		input = input.replace("+", "＋");
		input = input.replace("=", "＝");
		input = input.replace("/", "／");
		input = input.replace(" ", "　");

		
		//数字 英文字母 转化成全角
		
		input = input.replace("1", "１");
		input = input.replace("2", "２");
		input = input.replace("3", "３");
		input = input.replace("4", "４");
		input = input.replace("5", "５");
		input = input.replace("6", "６");
		input = input.replace("7", "７");
		input = input.replace("8", "８");
		input = input.replace("9", "９");
		input = input.replace("0", "０");
		
		
		input = input.replace("a", "ａ");
		input = input.replace("b", "ｂ");
		input = input.replace("c", "ｃ");
		input = input.replace("d", "ｄ");
		input = input.replace("e", "ｅ");
		input = input.replace("f", "ｆ");
		input = input.replace("g", "ｇ");
		input = input.replace("h", "ｈ");
		input = input.replace("i", "ｉ");
		input = input.replace("j", "ｊ");
		input = input.replace("k", "ｋ");
		input = input.replace("l", "ｌ");
		input = input.replace("m", "ｍ");
		input = input.replace("n", "ｎ");
		input = input.replace("o", "ｏ");
		input = input.replace("p", "ｐ");
		input = input.replace("q", "ｑ");
		input = input.replace("r", "ｒ");
		input = input.replace("s", "ｓ");
		input = input.replace("t", "ｔ");
		input = input.replace("u", "ｕ");
		input = input.replace("v", "ｖ");
		input = input.replace("w", "ｗ");
		input = input.replace("x", "ｘ");
		input = input.replace("y", "ｙ");
		input = input.replace("z", "ｚ");
		
		input = input.replace("A", "Ａ");
		input = input.replace("B", "Ｂ");
		input = input.replace("C", "Ｃ");
		input = input.replace("D", "Ｄ");
		input = input.replace("E", "Ｅ");
		input = input.replace("F", "Ｆ");
		input = input.replace("G", "Ｇ");
		input = input.replace("H", "Ｈ");
		input = input.replace("I", "Ｉ");
		input = input.replace("J", "Ｊ");
		input = input.replace("K", "Ｋ");
		input = input.replace("L", "Ｌ");
		input = input.replace("M", "Ｍ");
		input = input.replace("N", "Ｎ");
		input = input.replace("O", "Ｏ");
		input = input.replace("P", "Ｐ");
		input = input.replace("Q", "Ｑ");
		input = input.replace("R", "Ｒ");
		input = input.replace("S", "Ｓ");
		input = input.replace("T", "Ｔ");
		input = input.replace("U", "Ｕ");
		input = input.replace("V", "Ｖ");
		input = input.replace("W", "Ｗ");
		input = input.replace("X", "Ｘ");
		input = input.replace("Y", "Ｙ");
		input = input.replace("Z", "Ｚ");
		
		return input;
		
	}


	/**
	 * 行数据 created by shili at 2018-8-1
	 */
	public class Row {
		private int mPage;
		private Phrase phrase;
		private float mX;
		private float mY;

		public Row(int mPage, Phrase phrase,float mX, float mY) {
			this.mPage = mPage;
			this.phrase = phrase;
			this.mX = mX;
			this.mY = mY;
		}

		public int getmPage() {
			return mPage;
		}

		public void setmPage(int mPage) {
			this.mPage = mPage;
		}


		public float getmX() {
			return mX;
		}

		public void setmX(float mX) {
			this.mX = mX;
		}

		public float getmY() {
			return mY;
		}

		public void setmY(float mY) {
			this.mY = mY;
		}

		public Phrase getPhrase() {
			return phrase;
		}

		public void setPhrase(Phrase phrase) {
			this.phrase = phrase;
		}
	}

}
